(function ($) {
    $.fn.yqTree = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqTree.methods[opts](this, param);
        }

        $this = this;
        var opt;
        if ($this.data("yqtype") == "yqTree") {
            var $uniqueID = $this.attr("ID");
            var opts_ = $.extend({}, options($this));
            destroy($this);
            $this = $("#" + $uniqueID);
            opt = $.extend(opts_, opts);

            delete opt.toolbar;
        }
        else {
            opt = $.extend({}, $.fn.yqTree.defaults, opts);
            var $uniqueID = $this.attr("ID");
            if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                $uniqueID = $.getUniqueID();
                $this.attr("ID", $uniqueID);
            }
        }

        //---前处理，兼容输入设置错误
        if (opt.bindingKeyId == "") {
            opt.bindingKeyId = null;
        }
        if (opt.bindingValue == "") {
            opt.bindingValue = null;
        }
        if (opt.pKeyValue == "") {
            opt.pKeyValue = null;
        }
        //-------------------------

        opt.innerEdit_ = true;//外部删除、注销等操作附加按钮，默认是系统操作

        //组件加载结束
        opt.onload = true;
        //组件进程执行中
        opt.running = false;

        opt.defaultEdit = opt.isEdit;


        if (opt.overflowY) {
            if (opt.width === undefined) {
                opt.width = $this.width();
            }
            if (opt.height === undefined) {
                opt.height = $this.height();
            }

            if (opt.width == 0) {
                opt.width = $(window).width();
            }
            if (opt.height == 0) {
                opt.height = $(window).height();
            }
        }

        //转换编辑尺寸
        if (typeof opt.editModeW == "string") {
            var r_str = opt.editModeW.substring(opt.editModeW.length - 1, opt.editModeW.length);
            if (r_str == "%") {
                var wSacle = parseInt(opt.editModeW.substring(0, opt.editModeW.length - 1));
                opt.editModeW = parseInt(wSacle * $(window).width() / 100);
            } else {
                opt.editModeW = parseInt(opt.editModeW);
            }
        }
        if (typeof opt.editModeH == "string") {
            var r_str = opt.editModeH.substring(opt.editModeH.length - 1, opt.editModeH.length);
            if (r_str == "%") {
                var wSacle = parseInt(opt.editModeH.substring(0, opt.editModeH.length - 1));
                opt.editModeH = parseInt(wSacle * $(window).height() / 100);
            } else {
                opt.editModeH = parseInt(opt.editModeH);
            }
        }

        //editModeH: 450, //模态编辑器高度 格式为 600（数字） 

        $this.removeAttr("style");

        //变量信息
        $this.data("tree_opt", opt);
        $this.data("yqtype", "yqTree");

        LoadJsCss($this, function () {
            get_titles($this);
        })

    };

    $.fn.yqTree.defaults = {
        ajaxUrl: "/_db.html", //ajax地址
        dbname: "yqbase",   //数据库
        tbname: null,       //表
        keyId: "sid",       //关键字段
        displayMember: "name",          //显示字段,name 或 {name}
        bindingKeyId: null,
        bindingValue: null,
        pKeyId: "pid",
        pKeyValue: null,

        titles: [],  //数据列配置对象
        tempno: -1,  //数据模板no

        addWhere: "",  //附加条件       

        checkBoxCol: false,   //节点择复选框

        editTitle: "编辑",//编辑窗体标题
        editMode: 2,   //1,2,3-弹出编辑模态窗体, 4-弹出模态窗体，独立编辑文件
        editType: 1,    //editMode=1,2,3时  1:属性编辑模式  2:form编辑模式
        editModeW: 600, //模态编辑器宽度 格式为 800（数字） 或 90%（窗体比例）
        editModeH: 450, //模态编辑器高度 格式为 600（数字）  或 90%（窗体比例）
        editModeNo: -1, //编辑模板

        loadDefault: false,   //加载默认值
        blankTag: "*",        //值不能为空，标题附加标记

        menuType: 3,   //1-顶部菜单，2-右键菜单，3-顶部+右键  其他，无菜单
        btnMini: true, //按钮最小化
        isEdit: true, //可编辑
        copy: true,
        addroot: true,
        add: true,
        append: true,
        upp: true,
        del: true,
        isdel: false, //可注销
        isdel_field: "isdel", //注销使用的字段
        isdelEdit: true, //注销是否可编辑
        state: false,   //可状态编辑
        state_field: "state",//状态字段
        wflock: false,        //可流程控制
        move: true, //可移动
        cut: true,
        editLinks: [],  //显示的链接菜单
        editMenus: [],  //显示在其它中的菜单
        popMenuWidth: 150,     //右键菜单第一层宽度

        editLinks_r: [],  //右侧菜单

        editAlert: true,  //删除、注销提醒
        editLoadData: false, //添加、修改后更新数据库数据

        moveModeW: 800, //模态编辑器宽度 格式为 800（数字）
        moveModeH: 600, //模态编辑器高度 格式为 600（数字）
        moveModeNo: 1,  //移动模板

        actionAdd: {}, //SaveData附加参数
        filePathNo: null, //文件目录
        loadDataType: 2,   //加载结构树类型，1-全部加载模式，其他-递进加载模式
        initData: false, //初始化加载数据
        wf: null, //工作流

        isClCatch: false,                  //清理数据缓存
        catchTable: null,                  //清理文件 

        overflowY: true,
        //width: 300,
        //height: 100,

        checkbox: false, //复选框

        border: true,

        beforeBindingTitle: function (titles, callback) {
            callback(titles);
        }, //标题绑定前
        afterBindingTitle: function () { }, //标题绑定后
        beforeLoadData: function (opts, callback) {   //opts：查询参数，data：未null时，默认查询；不是null，外部查询
            var data = null;
            callback(opts, data);
        },
        beforeLoadSubData: function (opts, callback) {   //opts：查询参数，data：未null时，默认查询；不是null，外部查询
            var data = null;
            callback(opts, data);
        },
        beforeSetdata: function (data, callback) {
            callback(data)
        }, //绑定数据之前
        afterSetdata: function (data) { }, //绑定数据之后

        onClick: function (node) {     //节点点击

        },
        onDblClick: function (node) {    //节点双击

        },

        btnAction: function (action, params, callback) {   //头部菜单执行动作，返回true为执行默认选择操作
            callback(true);
        },
        uppActionState: function (s_node, callback) {     //操作节点状态处理接口(按钮操作状态处理接口)
            callback(true);
        },
        onBeforeShowEdit: function (titles, action, row, callback) {      //add/upp/move 编辑执行前
            callback(true, titles, row);      //true 执行编辑
        },
        beforeDataAction: function (d_rows, callback) {    //修改之前，true 执行
            callback(true, d_rows);
        },
        beforeEditNodeToUI: function (node) {    //节点编辑后加载前node处理
            return node;
        },
        afterDataAction: function (rows, res) {    //修改之后，true 默认界面处理

        },

        lines: true,
        animate: true,   //节点展开或折叠时显示动画效果。
        formatter: function (node) {
            return node.text;
        },


        copyText: "Copy",
        addRootText: "Add",
        addText: "Add",
        uppText: "Upp",
    };

    $.fn.yqTree.methods = {
        options: function (jq) {
            return options(jq);
        },
        destroy: function (jq) {
            destroy(jq);
        },
        toolbar: function (jq) {
            return options(jq).toolbar;
        },
        btnEnable: function (jq, id) {
            var toolbar = options(jq).toolbar;
            if (typeof toolbar != "undefined") {
                toolbar.yqEditMenu("enable", id);
            }
        },
        btnDisable: function (jq, id) {
            var toolbar = options(jq).toolbar;
            if (typeof toolbar != "undefined") {
                toolbar.yqEditMenu("disable", id);
            }
        },

        setBindingValue: function (jq, bindingValue) {
            var opt = options(jq);
            opt.bindingValue = bindingValue;
            opt.prewhere = "*";

            uppActionState(jq);
        },
        setPKeyValue: function (jq, pKeyValue) {
            var opt = options(jq);
            opt.pKeyValue = pKeyValue;
            opt.prewhere = "*";
        },
        appendRow: function (jq, row) {
            addNode_data(jq, row);
        },
        updateRow: function (jq, row) {
            uppNode_data(jq, row);
        },
        deleteRow: function (jq, row) {
            delNode_data(jq, row)
        },
        addRow: function (jq, row) { //添加行(进行数据库数据添加处理)
            showEditAfter(jq, "add", row);
        },
        uppRow: function (jq, row) { //修改行(进行数据库数据修改处理)
            showEditAfter(jq, "upp", row);
        },
        delRow: function (jq, row) {  //删除行(进行数据库数据删除处理)
            var $object = jq;
            options($object).innerEdit_ = false;
            del_run($object, row);
        },

        find: function (jq, id) {
            return jq.tree("find", id);
        },
        getSelected: function (jq) {
            return jq.tree("getSelected");
        },
        getChecked: function (jq) {
            return jq.tree("getChecked");
        },
        getRoots: function (jq) {
            var opt = options(jq);
            return jq.tree("getRoots");
        },
        getChildren: function (jq, node) {
            return jq.tree("getChildren", node.target);
        },
        getParent: function (jq, node) {
            return jq.tree("getParent", node.target);
        },
        expand: function (jq, id) {
            var node = jq.tree('find', id);
            if (node != null) {
                jq.tree("expand", node.target);
            }
        },
        collapse: function (jq, id) {
            var node = jq.tree('find', id);
            if (node != null) {
                jq.tree("collapse", node.target);
            }
        },
        check: function (jq, id) {
            var node = jq.tree('find', id);
            if (node != null) {
                jq.tree("check", node.target);
            }
        },
        uncheck: function (jq, id) {
            var node = jq.tree('find', id);
            if (node != null) {
                jq.tree("uncheck", node.target);
            }
        },
        actionState: function (jq, para) {    //外部触发更新操作状态事件，为其他区域启动操作按钮之用
            uppActionState(jq, para.s_node, function (tf) {
                para.callback(tf);
            });
        },
        resize: function (jq, para) {
            return jq.each(function () {
                resize(jq, para)
            });
        },
        clear: function (jq) {
            jq.tree("loadData", []);
        },
        loadData: function (jq) {
            jq.tree("loadData", []);
            loadData(jq);
        },
        isEdit: function (jq, tf) {
            isEdit(jq, tf);
        }
    };

    function LoadJsCss($object, callback) {
        var opt = options($object);
        var file = [];
        file.push({ url: "/scripts/crypto/sha256.min.js", type: "js" });
        $.yqLoadJsCss(file, function () {
            callback();
        })
    }

    function options($object) {
        return $object.data("tree_opt");
    }

    function form_load($object) {
        var opt = options($object);
        if (opt.menuType == 2 || opt.menuType == 3) {
            //--------------------
            opt.tree_panel.data("_object", $object);
            opt.tree_panel.bind('contextmenu', function (e) {
                var $obj = $(this).data("_object");
                uppActionState($obj, $obj.tree("getSelected"),
                    function (tf) {
                        if (tf) {
                            e.preventDefault();
                            opt.toolbar.yqEditMenu("open", e);
                        }
                    });
            });
            //---------------
        }

        resize($object, { width: opt.width, height: opt.height });
        opt.onload = false;
        opt.afterBindingTitle.call($object);

        var $tr1 = $($object.closest('table.yqtree').children()[0]);
        if ($tr1.height() < 10) {
            $tr1.hide();
        }
    }

    function destroy($object) {
        var opt = options($object);
        var $tb = $object.closest('table.yqtree');

        var toolbar = opt.toolbar;
        if (typeof toolbar != "undefined") {
            toolbar.yqEditMenu("destroy");
        }
        $tb.before($object);
        $tb.remove();
        $object.empty();

        $object.removeData("tree_opt");
        $object.removeData("yqtype");
    }

    function get_titles($object) {
        var opt = options($object);

        if (opt.titles.length > 0) {
            opt.titles = $.yqFmUiTitle(opt.titles);
            opt.beforeBindingTitle.call($object, opt.titles,
                function (_titles) {
                    opt.titles = _titles;
                    init_tree($object);
                });
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.tempno
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.titles = $.yqFmUiTitle(res.titles);

                    opt.beforeBindingTitle.call($object, opt.titles,
                        function (_titles) {
                            opt.titles = _titles;
                            init_tree($object);
                        });
                }
                else {
                    console.log(res);
                    $.yqMessager("error", res.info + "[" + res.error + "]");
                }
            })
        }
    }

    function init_tree($object) {
        var opt = options($object);

        var $table = $('<table class="yqtree ' + (opt.border ? "bkdiv " : "") + 'panel" style="width:100%;border-spacing: 0px;"></table>');
        var $tr = $('<tr class="panel-header"></tr>');
        $tr.css({
            "border-width": "0px"
        });
        $table.append($tr);

        var $td1 = $('<td></td>');
        $tr.append($td1);
        $tr = $("<tr></tr>");
        $table.append($tr);
        var $td2 = $('<td></td>');
        $td2.css({
            "padding": "0px",
            "margin": "0px",
        });
        var $div = $('<div class="treebody"></div>'); // style="overflow: auto;width:100%;height:300px;"
        $td2.append($div)
        $tr.append($td2);

        $object.after($table);
        $div.append($object);

        if (opt.overflowY) {
            $div.css({ "overflow": "auto" });
            $div.width(opt.width);
            $div.height(opt.height - 48);

            opt.tree_panel = $div;
        }

        if (opt.menuType == 1 ||
            opt.menuType == 2 ||
            opt.menuType == 3 ||
            opt.editLinks_r.length > 0) {
            var $menu = $('<div></div>');
            opt.toolbar = $menu;
            $td1.append($menu);

            $menu.yqEditMenu({
                type: opt.menuType,  //1(!=2或3)-顶部菜单，2-右键菜单，3-顶部+右键
                mini: opt.btnMini,
                copy: opt.copy,
                addroot: opt.addroot,
                append: opt.append,
                add: opt.add,
                upp: opt.upp,
                del: opt.del,
                save: false,
                isdel: opt.isdel,
                cut: opt.cut,
                state: opt.state,
                state_field: opt.state_field,
                move: opt.move,
                links: opt.editLinks,  //显示的链接菜单
                menus: opt.editMenus,  //显示在其它中的菜单
                width: opt.popMenuWidth,  //右键菜单第一层宽度
                links_r: opt.editLinks_r,
                isSimple: false,
                isSeek: false,
                titles: opt.titles,

                onClick: function (action, params) {
                    opt.btnAction.call($object, action, params, function (tf) {
                        if (tf) {
                            btnAction($object, action, params);
                        }
                    });
                }
            });
        }

        $object.tree({
            lines: opt.true,
            animate: opt.true,   //节点展开或折叠时显示动画效果。
            checkbox: opt.checkbox,
            formatter: function (node) {
                return opt.formatter.call($object, node);
            },
            onLoadSuccess: function (node, data) {
                opt.running = false;
                opt.afterSetdata.call($object, data);

                uppActionState($object, null, function (tf) {

                });

                if (opt.onload) {
                    form_load($object);
                }

                opt.onClick.call($object, null);
            },
            onClick: function (node) {
                opt.prevent_e = $.getPreventDefault(node.target);
                opt.prevent_e.id = $object.attr("id");
                opt.prevent_e.options = opt;

                if (opt.menuType == 1 || opt.menuType == 3) {
                    uppActionState($object, node, function (tf) {
                        opt.onClick.call($object, node);
                    });
                }
                else {
                    opt.onClick.call($object, node);
                }
            },
            onDblClick: function (node) {
                opt.onDblClick.call($object, node);
            },
            onBeforeExpand: function (node) {
                if (opt.loadDataType != 1) {
                    loadSubNode($object, node);
                }

                //opt.onBeforeExpand.call($object, node);
            },
            onContextMenu: function (e, node) {
                if (opt.menuType == 2 || opt.menuType == 3) {
                    uppActionState($object, node, function (tf) {
                        if (tf) {
                            e.preventDefault();

                            opt.prevent_e = {
                                "clientX": e.clientX,
                                "clientY": e.clientY
                            };
                            opt.prevent_e.id = $object.attr("id");
                            opt.prevent_e.options = opt;
                            opt.toolbar.yqEditMenu("open", e);
                        }
                    });
                }
            },
        });

        if (opt.loadData && ((opt.bindingKeyId === null && opt.bindingValue === null)
            || (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)))) {
            loadData($object);
        }
        else {
            form_load($object);
            uppActionState($object);
        }
    }

    //加载数据
    function loadData($object) {
        var opt = options($object);

        if ((!(opt.bindingKeyId === null) && opt.bindingValue === null)) {
            if (!opt.onload) {
                setData($object, { rows: [] });
            }

            return;
        }

        if (opt.running) {
            return;
        }

        opt.running = true;

        var l_where = "";

        if (!(opt.addWhere === null) && opt.addWhere != "") {
            l_where = opt.addWhere;
        }

        var bindWhere = "";
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            bindWhere = opt.bindingKeyId + " = '" + opt.bindingValue + "'";
        }

        if (opt.loadDataType != 1) {   //分级加载模式
            if (opt.pKeyValue === null) {
                bindWhere += (bindWhere == "" ? "" : " and ") + opt.pKeyId + " is null";
            }
            else {
                bindWhere += (bindWhere == "" ? "" : " and ") + opt.pKeyId + "='" + opt.pKeyValue + "'";
            }
        }

        if (bindWhere != "") {
            if (l_where == "") {
                l_where = bindWhere;
            } else {
                l_where = "(" + l_where + ") and (" + bindWhere + ")";
            }
        }

        var pp_opt = {
            url: opt.ajaxUrl,
            dbname: opt.dbname,
            tbname: opt.tbname,
            where: l_where,
            order: "queue"
        };
        if (typeof opt._appno != undefined) {
            pp_opt.ctrlid = opt._ctrlid;
            pp_opt.appno = opt._appno;
            pp_opt.menuno = opt._menuno;
        }

        opt.beforeLoadData.call($object, pp_opt,
            function (_pp_opt, _data) {
                if (_data === null) {
                    $.yqDbTbSelect(_pp_opt, function (data) {
                        if (data.error == 0) {
                            setData($object, data.rows)
                        }
                        else {
                            opt.running = false;
                            if (opt.onload) {
                                form_load($object);
                            }
                        }
                    })
                } else {
                    if (_data.error == 0) {
                        setData($object, _data.rows)
                    }
                    else {
                        opt.running = false;
                        if (opt.onload) {
                            form_load($object);
                        }
                    }
                }
            });
    }

    //加载下一级数据
    function loadSubData($object, ids, callback) {
        var opt = options($object);
        var $uniqueID = $object.attr("ID");

        if (ids.length == 0) {
            callback({ "error": 0, "rows": [] });
            return;
        }

        var l_where = "";
        for (var i = 0; i < ids.length; i++) {
            l_where += (l_where == "" ? "" : ",") + "'" + ids[i] + "'";
        }

        l_where = opt.pKeyId + " in (" + l_where + ")";

        var pp_opt = {
            url: opt.ajaxUrl,
            dbname: opt.dbname,
            tbname: opt.tbname,
            where: l_where,
            order: "queue"
        };
        if (typeof opt._appno != undefined) {
            pp_opt.ctrlid = opt._ctrlid;
            pp_opt.appno = opt._appno;
            pp_opt.menuno = opt._menuno;
        }

        opt.beforeLoadSubData.call($object, pp_opt,
            function (_pp_opt, _data) {
                if (_data === null) {
                    $.yqDbTbSelect(_pp_opt, function (data) {
                        callback(data);
                    });
                } else {
                    $.yqDbTbSelect(pp_opt, function (data) {
                        callback(_data);
                    });
                }
            });
    }

    function setData($object, rows) {
        var opt = options($object);
        rows = $.yqFmToViews(rows, opt.titles);   //数据加载格式处理
        if (opt.loadDataType == 1) {   //全局加载模式
            opt.beforeSetdata.call($object, rows, function (_rows) {
                $.yqToTrees({
                    pidVal: opt.pKeyValue,              //根节点父项属性值
                    idName: opt.keyId,             //id字段名称
                    pidName: opt.pKeyId,            //pid字段名称
                    displayMember: opt.displayMember,      //显示字段
                    rows: _rows                    //数据         
                }, function (data) {
                    $object.tree("loadData", data);
                })
            });
        }
        else {
            var ids = [];
            for (var i = 0; i < rows.length; i++) {
                ids.push(rows[i][opt.keyId]);
            }

            loadSubData($object, ids, function (res) {
                if (res.error == 0) {
                    var a_rows = $.extend([], rows);
                    res.rows = $.yqFmToViews(res.rows, opt.titles);   //数据加载格式处理
                    for (var j = 0; j < res.rows.length; j++) {
                        var row = $.extend({}, res.rows[j]);
                        a_rows.push(row);
                    }

                    opt.beforeSetdata.call($object, a_rows, function (_rows) {
                        $.yqToTrees({
                            pidVal: opt.pKeyValue,              //根节点父项属性值
                            idName: opt.keyId,             //id字段名称
                            pidName: opt.pKeyId,            //pid字段名称
                            displayMember: opt.displayMember,      //显示字段
                            rows: _rows                    //数据         
                        }, function (nodes) {
                            for (let n = 0; n < nodes.length; n++) {
                                nodes[n]["_1"] = true;  //下一级数据加载标识 true 加载
                                if (nodes[n].children > 0) {
                                    for (let n2 = 0; n2 < nodes[n].children.length; n2++) {
                                        nodes[n].children[n2] = false; //下一级数据加载标识 false 未加载
                                    }
                                }

                            }

                            $object.tree("loadData", nodes);
                        })
                    });
                }
                else {
                    opt.running = false;
                    if (opt.onload) {
                        form_load($object);
                    }
                }
            })
        }
    }

    //加载次一级数据
    function loadSubNode($object, node) {
        var opt = options($object);
        var nodes = node.children;
        if (nodes.length == 0) {
            return;
        }

        if (nodes[0]["_1"]) {
            return;
        }

        var ids = [];
        for (var i = 0; i < nodes.length; i++) {
            nodes[i]["_1"] = true;
            ids.push(nodes[i]["id"]);
        }

        loadSubData($object, ids, function (res) {
            if (res.error == 0) {
                opt.beforeSetdata.call($object, $.yqFmToViews(res.rows, opt.titles), function (_rows) {
                    for (var i = 0; i < nodes.length; i++) {
                        children = [];
                        for (var j = 0; j < _rows.length; j++) {
                            if (nodes[i]["id"] == _rows[j][opt.pKeyId]) {
                                var row = _rows[j];
                                var node = {
                                    "id": row[opt.keyId],
                                    "text": $.getDisplayValue(row, opt.displayMember),
                                    "attributes": row,
                                    "_1": false,  //下一级数据加载标识 false 未加载
                                    "state": "open"
                                };

                                if (typeof row.iconCls == "string") {
                                    node.iconCls = row.iconCls;
                                }

                                children.push(node);
                            }
                        }

                        var c_node = $object.tree('find', nodes[i]["id"]);
                        if (children.length > 0) {
                            $object.tree('append', {
                                parent: c_node.target,
                                data: children
                            });

                            $object.tree('collapse', c_node.target);
                        }
                        else {
                            delete c_node["state"];
                        }
                    }
                });
            }
            else {

            }
        })
    }

    function resize($object, para) {
        var opt = options($object);
        if (typeof para.width != "undefined") {
            opt.width = para.width;
        }
        if (typeof para.height != "undefined") {
            opt.height = para.height;
        }

        //opt.tree_panel.closest('table.yqtree').css({ "width": opt.width + 15 });
        var cut_border = opt.border ? 2 : 0;
        if (opt.overflowY) {
            if (opt.menuType == 1 || opt.menuType == 3) {
                opt.tree_panel.css({ "width": opt.width - cut_border, "height": (opt.height - 36 - cut_border) });
            } else {
                opt.tree_panel.css({ "width": opt.width - cut_border, "height": opt.height - cut_border });
            }
        } else {
            opt.tree_panel.css({ "width": opt.width - cut_border });
        }
    }

    function isEdit($object, tf) {
        var opt = options($object);
        opt.isEdit = tf;
        var node = $object.tree("getSelected");
        uppActionState($object, node);
    }

    function btnAction($object, action, params) {
        var opt = options($object);

        if (params === undefined) {
            params = {};
        }

        opt.innerEdit_ = true;
        const actionHandlers = {
            "copy": btn_copy,
            "addroot": btn_addroot,
            "add": btn_add,
            "upp": btn_upp,
            "del": btn_del,
            "isdel1": (obj) => btn_isdel(obj, true),
            "isdel0": (obj) => btn_isdel(obj, false),
            "cut": btn_cut,
            "uncut": btn_uncut,
            "pasteroot": btn_pasteroot,
            "paste": btn_paste,
            "state": (obj) => btn_state(obj, params),
            "move": btn_move,
        };

        if (action in actionHandlers) {
            actionHandlers[action]($object);
        } else {
            //opt.btnAction.call($object, params, action);
            console.warn("未知的操作: ", action); // 添加默认处理逻辑
        }
    }

    //更新操作状态信息
    function uppActionState($object, s_node, callback) {
        var opt = options($object);
        if (!(opt.menuType == 1 || opt.menuType == 2 || opt.menuType == 3)) {
            if (callback) {
                callback(true);
            }
            return;
        }

        if (s_node === undefined) {
            s_node = $object.tree("getSelected");
        }
        if (!(opt.bindingKeyId === null) && opt.bindingValue === null) {
            if (opt.addroot) {
                opt.toolbar.yqEditMenu("disable", "addroot");
            }
            if (opt.copy) {
                opt.toolbar.yqEditMenu("disable", "copy");
            }
            if (opt.append) {
                opt.toolbar.yqEditMenu("disable", "append");
            }
            if (opt.add) {
                opt.toolbar.yqEditMenu("disable", "add");
            }
            if (opt.upp) {
                opt.toolbar.yqEditMenu("disable", "upp");
            }
            if (opt.del) {
                opt.toolbar.yqEditMenu("disable", "del");
            }
            if (opt.isdel) {
                opt.toolbar.yqEditMenu("disable", "isdel1");
                opt.toolbar.yqEditMenu("disable", "isdel0");
            }
            if (opt.state) {
                opt.toolbar.yqEditMenu("disable", "state");
            }
            if (opt.move) {
                opt.toolbar.yqEditMenu("disable", "move");
            }

            if (opt.cut) {
                opt.toolbar.yqEditMenu("disable", "cut");
                opt.toolbar.yqEditMenu("disable", "uncut");
                opt.toolbar.yqEditMenu("disable", "pasteroot");
                opt.toolbar.yqEditMenu("disable", "paste");
            }

            opt.uppActionState.call($object, s_node, function (tf) {     //操作节点状态处理接口
                if (callback) {
                    callback(tf);
                }
            });

            return;
        }

        var is_edit = opt.isEdit;
        if (is_edit && !(s_node === null) && opt.wflock) {
            if (s_node.attributes["wflock"]) {
                is_edit = false;
            }
        }
        //todo 按钮处理
        if (opt.copy) {
            opt.toolbar.yqEditMenu(((is_edit == false || s_node === null) ? "disable" : "enable"), "copy");
        }
        if (opt.addroot) {
            opt.toolbar.yqEditMenu((is_edit == false ? "disable" : "enable"), "addroot");

        }
        if (opt.append) {
            opt.toolbar.yqEditMenu(((is_edit == false || s_node === null) ? "disable" : "enable"), "append");
        }
        if (opt.add) {
            opt.toolbar.yqEditMenu(((is_edit == false || s_node === null) ? "disable" : "enable"), "add");
        }

        if (opt.upp) {
            opt.toolbar.yqEditMenu((s_node === null ? "disable" : "enable"), "upp");
        }

        if (opt.del) {
            var del = false;
            if (!(s_node === null)) {
                if ($object.tree("getChildren", s_node.target).length == 0) {
                    if (opt.isdel && opt.isdelEdit == false) {
                        if (s_node.attributes[opt.isdel_field] == false) {
                            del = true;
                        }
                    }
                    else {
                        del = true;
                    }
                }
            }

            opt.toolbar.yqEditMenu(((is_edit == false || del == false) ? "disable" : "enable"), "del");
        }

        if (opt.isdel) {
            var isdel1 = false;
            var isdel0 = false;
            if (!(s_node === null)) {
                if (s_node.attributes[opt.isdel_field]) {
                    isdel0 = true;
                }
                else {
                    isdel1 = true;
                }
            }
            opt.toolbar.yqEditMenu(((is_edit == false || isdel1 == false) ? "disable" : "enable"), "isdel1");
            opt.toolbar.yqEditMenu(((is_edit == false || isdel0 == false) ? "disable" : "enable"), "isdel0");
        }

        if (opt.state) {
            if (s_node === null || !is_edit) {
                opt.toolbar.yqEditMenu("disable", "state");
            }
            else {
                var state_value = s_node.attributes[opt.state_field];
                var state_lists = [];
                for (var i = 0; i < opt.titles.length; i++) {
                    if (opt.titles[i].name == opt.state_field) {
                        state_lists = opt.titles[i].ui_mask.lists;
                        break;
                    }
                }
                if (state_lists === undefined) {
                    state_lists = [];
                }
                opt.toolbar.yqEditMenu((state_lists.length == 0 ? "disable" : "enable"), "state");
                for (var i = 0; i < state_lists.length; i++) {
                    opt.toolbar.yqEditMenu((state_value == state_lists[i].no ? "disable" : "enable"), "state_" + state_lists[i].no);
                }
            }
        }

        if (opt.cut) {
            var cut = (s_node === null ? false : true);
            if (!(opt._cut_node === undefined) && !(s_node === null)) {
                if (opt._cut_node.id == s_node.id) {
                    cut = false;
                }
            }
            opt.toolbar.yqEditMenu(((is_edit == false || cut == false) ? "disable" : "enable"), "cut");

            opt.toolbar.yqEditMenu(((is_edit == false || opt._cut_node === undefined) ? "disable" : "enable"), "uncut");

            var pasteroot = false;
            var paste = false;
            if (!(opt._cut_node === undefined)) {
                pasteroot = true;
                if (((opt._cut_node.attributes[opt.pKeyId] === undefined
                    || opt._cut_node.attributes[opt.pKeyId] === null) && opt.pKeyValue === null)
                    || (opt._cut_node.attributes[opt.pKeyId] == opt.pKeyValue)) {
                    pasteroot = false;
                }

            }
            opt.toolbar.yqEditMenu(((is_edit == false || pasteroot == false) ? "disable" : "enable"), "pasteroot");


            if (!(opt._cut_node === undefined) && !(s_node === null)) {
                paste = true;
                if (!(opt._cut_node.id == s_node.id ||
                    opt._cut_node.attributes[opt.pKeyId] == s_node.id)) {
                    paste = true;
                    var p_node = s_node;
                    while (opt._cut_node.id != p_node.id) {
                        var p_node = $object.tree("getParent", p_node.target);
                        if (p_node === null) {
                            break;
                        }
                        else if (opt._cut_node.id == p_node.id) {
                            paste = false;
                        }
                    }
                }
                else {
                    paste = false;
                }
            }
            opt.toolbar.yqEditMenu(((is_edit == false || paste == false) ? "disable" : "enable"), "paste");
        }

        if (opt.move) {
            var move = false;
            if (!(s_node === null)) {
                var parent = $object.tree("getParent", s_node.target);
                if (!(parent === null)) {
                    if (parent.children.length > 0) {
                        move = true;
                    }
                }
                else {
                    if ($object.tree("getRoots").length > 0) {
                        move = true;
                    }
                }
            }

            opt.toolbar.yqEditMenu(((is_edit == false || move == false) ? "disable" : "enable"), "move");
        }


        opt.uppActionState.call($object, s_node, function (tf) {     //操作节点状态处理接口
            if (callback) {
                callback(tf);
            }
        });
    }

    function btn_copy($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = $.extend({}, node.attributes);
        delete row[opt.keyId];

        showEdit($object, "add", row);
    }

    function btn_addroot($object) {
        var opt = options($object);
        var row = {};
        row[opt.pKeyId] = opt.pKeyValue;
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            row[opt.bindingKeyId] = opt.bindingValue;
        }

        showEdit($object, "add", row);
    }

    function btn_append($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = {};
        row[opt.pKeyId] = node.attributes[opt.pKeyId];
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            row[opt.bindingKeyId] = opt.bindingValue;
        }

        showEdit($object, "add", row);
    }

    function btn_add($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = {};
        row[opt.pKeyId] = node.attributes[opt.keyId];
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            row[opt.bindingKeyId] = opt.bindingValue;
        }

        showEdit($object, "add", row);
    }

    function btn_upp($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = $.extend({}, node.attributes);

        showEdit($object, "upp", row);
    }

    function showEdit($object, action, row) {
        var opt = options($object);

        if (opt.prevent_e === undefined) {
            opt.prevent_e = {};
            opt.prevent_e.clientX = 0;
            opt.prevent_e.clientY = 0;
            opt.prevent_e.id = $object.attr("id");
            opt.prevent_e.options = opt;
        }
        var mdiinfo = $.yqGetWindParams();
        //editType
        if (opt.editMode == 1 ||
            opt.editMode == 2 ||
            opt.editMode == 3) {
            if (opt.editType == 1) {
                getEditTitles($object, function (titles) {
                    opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                        if (tf) {
                            var run_opt = {
                                ajaxUrl: opt.ajaxUrl,
                                mdiinfo: mdiinfo,
                                prevent_e: opt.prevent_e,
                                width: opt.editModeW,
                                height: opt.editModeH,
                                titles: _titles,
                                action: action,
                                row: _row,
                                isEdit: opt.isEdit,

                                loadDefault: opt.loadDefault,   //加载默认值
                                blankTag: opt.blankTag,        //值不能为空，标题附加标记

                                title: opt.editTitle,
                                width: opt.editModeW,
                                height: opt.editModeH,

                                dbname: opt.dbname,

                                callback: function (row_) {
                                    showEditAfter($object, action, row_);
                                }
                            };
                            if (window.top == window.self) {
                                $.yqAttrPopEdit(run_opt);
                            }
                            else {
                                window.top.$.yqAttrPopEdit(run_opt);
                            }
                        }
                    });
                });
            } else if (opt.editType == 2) {
                getEditModel($object, function (titles, model) {
                    opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                        if (tf) {
                            var run_opt = {
                                mdiinfo: mdiinfo,
                                prevent_e: opt.prevent_e,

                                ajaxUrl: opt.ajaxUrl,
                                titles: _titles,
                                model: model,
                                action: action,
                                row: _row,
                                isEdit: opt.isEdit,

                                loadDefault: opt.loadDefault,   //加载默认值
                                blankTag: opt.blankTag,        //值不能为空，标题附加标记

                                title: opt.editTitle,
                                width: opt.editModeW,
                                height: opt.editModeH,

                                dbname: opt.dbname,

                                callback: function (row_) {
                                    showEditAfter($object, action, row_);
                                }
                            };

                            if (window.top == window.self) {
                                $.yqFormPopEdit(run_opt);
                            }
                            else {
                                window.top.$.yqFormPopEdit(run_opt);
                            }

                        }
                    });

                });
            }
        } else if (opt.editMode == 4) {
            getEditModel($object, function (titles, model) {
                opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                    if (tf) {
                        opt.prevent_e.p_target = $object;
                        opt.prevent_e.titles = _titles;
                        opt.prevent_e.model = model;
                        opt.prevent_e.action = action;
                        opt.prevent_e.row = _row;
                        opt.prevent_e.dbname = opt.dbname;

                        var edit_pops = {
                            prevent_e: opt.prevent_e,
                            mdiinfo: mdiinfo,
                            title: opt.editTitle,
                            width: opt.editModeW,
                            height: opt.editModeH,

                            url: "/adp/test/openedit.html",

                            onOpen: function () {
                                //console.log("onOpen");
                            },
                            onBeforeClose: function () {
                                //console.log("onBeforeClose");
                                return true;
                            },
                        };

                        if (window.top == window.self) {
                            $.yqWinPopEdit(edit_pops);
                        }
                        else {
                            window.top.$.yqWinPopEdit(edit_pops);
                        }
                    }
                });

            });
        }
    }

    function showEditAfter($object, action, row_) {
        var opt = options($object);

        if (action == "add") {
            delete row_[opt.keyId];
            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                row_[opt.bindingKeyId] = opt.bindingValue;
            }
            if (row_[opt.pKeyId] === undefined ||
                row_[opt.pKeyId] === null ||
                row_[opt.pKeyId] == "") {
                if (!(opt.pKeyValue === null)) {
                    row_[opt.pKeyId] = opt.pKeyValue;
                } else {
                    delete row_[opt.pKeyId]
                }
            }
        }

        var d_rows = [];
        var m_row = {
            action: action,
            row: row_
        }
        d_rows.push(m_row);
        dataAction($object, d_rows);
    }

    function getEditTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_titles != "undefined") {
            callback(opt.edit_titles);
        }
        else if (opt.tempno == opt.editModeNo) {
            opt.edit_titles = opt.titles;
            callback(opt.edit_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.editModeNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.edit_titles = opt.titles;
                }

                callback(opt.edit_titles);
            })
        }
    }

    //form编辑模式 begin
    function getEditModel($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_titles != "undefined") {
            getEditModel_($object, function (model) {
                callback(opt.edit_titles, model);
            });
        }
        else if (opt.tempno == -1) {
            opt.edit_titles = opt.titles;
            getEditModel_($object, function (model) {
                callback(opt.edit_titles, model);
            });
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: -1
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.edit_titles = opt.titles;
                }

                getEditModel_($object, function (model) {
                    callback(opt.edit_titles, model);
                });
            })
        }
    }

    function getEditModel_($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_model != "undefined") {
            callback(opt.edit_model);
        }
        else if (opt.tempno == opt.editModeNo) {
            opt.edit_model = JSON.stringify(opt.titles);
            callback(opt.edit_model);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.editModeNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbModel(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_model = res.model;
                } else {
                    //console.log(res);
                    opt.edit_model = JSON.stringify(opt.titles);
                }

                callback(opt.edit_model);
            })
        }
    }
    //form编辑模式  end

    function btn_del($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = {};
        row[opt.keyId] = node.id;

        del_run($object, row);
    }

    function del_run($object, row) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = {};
        row[opt.keyId] = node.id;

        if (opt.editAlert && opt.innerEdit_) {
            $.yqConfirm("删除", "是否确认?",
                function (r) {
                    if (r) {
                        dataAction($object, [{
                            "action": "del",
                            "row": row
                        }]);
                    }
                });
        } else {
            dataAction($object, [{
                "action": "del",
                "row": row
            }]);
        }
    }

    function btn_isdel($object, tf) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = {};
        row[opt.keyId] = node.id;
        row[opt.isdel_field] = tf;

        dataAction($object, [{
            "action": "upp_",
            "row": row
        }]);
    }

    function btn_cut($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        if (typeof opt._cut_node != "undefined") {
            $object.tree("update", {
                "target": opt._cut_node.target,
                "text": $.getDisplayValue(opt._cut_node.attributes, opt.displayMember)
            });
        }

        $object.tree("update", {
            "target": node.target,
            "text": '<i class="cut_node">' + $.getDisplayValue(node.attributes, opt.displayMember) + '<i/>'
        });

        opt._cut_node = node;

        uppActionState($object, node);
    }

    function btn_uncut($object) {
        var opt = options($object);
        if (typeof opt._cut_node != "undefined") {
            $object.tree("update", {
                "target": opt._cut_node.target,
                "text": $.getDisplayValue(opt._cut_node.attributes, opt.displayMember)
            });

            delete opt._cut_node;

            var node = $object.tree("getSelected");
            uppActionState($object, node);
        }
    }

    function btn_pasteroot($object) {
        var opt = options($object);
        if (opt._cut_node === undefined) {
            return;
        }

        var row = {
            "pid_field": opt.pKeyId
        };
        row[opt.keyId] = opt._cut_node.id;
        row[opt.pKeyId] = opt.pKeyValue;
        row[opt.pKeyId + "_old"] = opt._cut_node.attributes[opt.pKeyId];

        dataAction($object, [{
            "action": "paste",
            "row": row
        }]);
    }

    function btn_paste($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }
        var opt = options($object);

        var row = {
            "pid_field": opt.pKeyId
        };
        row[opt.keyId] = opt._cut_node.id;
        row[opt.pKeyId] = node.id;
        row[opt.pKeyId + "_old"] = opt._cut_node.attributes[opt.pKeyId];

        dataAction($object, [{
            "action": "paste",
            "row": row
        }]);
    }

    function btn_state($object, params) {
        var opt = options($object);
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }

        var opt = options($object);
        var row = {};
        row[opt.keyId] = node.id;
        row[opt.state_field] = params.no;

        dataAction($object, [{
            "action": "upp_",
            "row": row
        }]);
    }

    function btn_move($object) {
        var node = $object.tree("getSelected");
        if (node === null) {
            return;
        }
        var opt = options($object);
        var rows = [];
        var nodes;
        var parent = $object.tree("getParent", node.target);
        if (!(parent === null)) {
            nodes = parent.children;
        }
        else {
            nodes = $object.tree("getRoots");
        }

        for (var i = 0; i < nodes.length; i++) {
            rows.push($.extend({}, nodes[i].attributes));
        }

        getMoveTitles($object, function (titles) {
            opt.onBeforeShowEdit.call($object, titles, "move", rows,
                function (tf, _titles, _rows) {
                    if (tf) {
                        var mdiinfo = $.yqGetWindParams();
                        var move_opt = {
                            prevent_e: opt.prevent_e,
                            mdiinfo: mdiinfo,
                            //title: $.fn.yqUiExtText.DialogMoveTitle,
                            width: opt.moveModeW,
                            height: opt.moveModeH,

                            ajaxUrl: opt.ajaxUrl,
                            titles: _titles,
                            rows: _rows,
                            callback: function (_rows) {
                                var d_rows = [];
                                var ids = [];
                                var ids_ = [];
                                for (var i = 0; i < _rows.length; i++) {
                                    ids.push(_rows[i][opt.keyId]);
                                }

                                for (var j = 0; j < rows.length; j++) {
                                    ids_.push(rows[j][opt.keyId]);
                                }

                                if (JSON.stringify(ids) == JSON.stringify(ids_)) {
                                    return;
                                }

                                //剪切情况处理
                                btn_uncut($object);

                                var m_row = {
                                    "action": "move",
                                    "row":
                                    {
                                        "ids": ids
                                    }
                                }

                                if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                                    m_row.row["binding_field"] = opt.bindingKeyId;
                                    m_row.row[opt.bindingKeyId] = opt.bindingValue;
                                }
                                m_row.row["pid_field"] = opt.pKeyId;
                                m_row.row[opt.pKeyId] = node.attributes[opt.pKeyId];
                                d_rows.push(m_row);

                                //console.log(d_rows);
                                dataAction($object, d_rows);
                            }
                        };

                        if (window.self == window.top) {
                            $.yqRowsPopMove(move_opt);
                        }
                        else {
                            window.top.$.yqRowsPopMove(move_opt);
                        }
                    }
                });
        })
    }

    //取得移动编辑模板
    function getMoveTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.move_titles != "undefined") {
            callback(opt.move_titles);
        }
        else if (opt.tempno == opt.moveModeNo) {
            opt.move_titles = opt.titles;
            callback(opt.move_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.moveModeNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.move_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.move_titles = opt.titles;
                }

                callback(opt.move_titles);
            })
        }
    }

    function dataAction($object, rows) {
        var opt = options($object);
        //$.yqFmToData(rows[i], opt.titles)
        var a_rows = [];
        for (var i = 0; i < rows.length; i++) {
            var _row = { action: rows[i].action };
            if (rows[i].action == "add" || rows[i].action == "upp") {
                _row.row = $.yqFmToData(rows[i].row, opt.titles);
            }
            else {
                _row.row = rows[i].row;
            }

            a_rows.push(_row);
        }

        opt.beforeDataAction.call($object, a_rows,
            function (tf, _a_rows) {
                if (tf) {
                    var file_titles = getFile_edit_titles();
                    //保存前，文件上传处理
                    if (file_titles.length > 0) {
                        $.yqFilesUpload(file_titles, _a_rows, function (__a_rows) {
                            for (let jj = 0; jj < __a_rows.length; jj++) {
                                for (let ii = 0; ii < file_titles.length; ii++) {
                                    rows[jj].row[file_titles[ii].field_name] = __a_rows[jj].row[file_titles[ii].field_name];
                                }
                            }

                            toDB(__a_rows, file_titles);
                        })
                    } else {
                        toDB(_a_rows, null);
                    }
                }
            });

        //获取文件字段
        function getFile_edit_titles() {
            if (opt.f_edit_titles === undefined) {
                //文件处理
                opt.f_edit_titles = [];
                if (typeof opt.edit_titles === "object") {
                    for (let i = 0; i < opt.edit_titles.length; i++) {
                        if (opt.edit_titles[i].ui_type == 18 ||
                            opt.edit_titles[i].ui_type == 19) {
                            opt.f_edit_titles.push({
                                field_type: opt.edit_titles[i].ui_type,
                                field_name: opt.edit_titles[i].name,
                                sto_type: opt.edit_titles[i].ui_mask.storageType,
                                sto_name: (opt.edit_titles[i].ui_mask.storageType == 1 ? opt.dbname : opt.edit_titles[i].ui_mask.storageName),
                                chunk: opt.edit_titles[i].ui_mask.chunk
                            });
                        }
                    }
                } else {
                    for (let i = 0; i < opt.titles.length; i++) {
                        if (opt.titles[i].ui_type == 18 ||
                            opt.titles[i].ui_type == 19) {
                            opt.f_edit_titles.push({
                                field_type: opt.titles[i].ui_type,
                                field_name: opt.titles[i].name,
                                sto_type: opt.titles[i].ui_mask.storageType,
                                sto_name: (opt.titles[i].ui_mask.storageType == 1 ? opt.dbname : opt.titles[i].ui_mask.storageName),
                                chunk: opt.titles[i].ui_mask.chunk
                            });
                        }
                    }
                }
            }

            return opt.f_edit_titles;
        }

        function toDB(a_rows, file_params) {
            var a_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                rows: a_rows,
            };
            if (typeof opt._appno != undefined) {
                a_opt.ctrlid = opt._ctrlid;
                a_opt.appno = opt._appno;
                a_opt.menuno = opt._menuno;
            }

            if (typeof file_params == "object") {
                a_opt.fileparm = file_params;
            }

            $.yqDbAction(a_opt,
                function (res) {
                    dataAction_($object, rows, res);
                });
        }
    }

    function dataAction_($object, rows, res) {
        var opt = options($object);

        if (res.error == 0) {
            var error = "";
            if (res.rows[0].error == 0) {
                if (res.rows[0].action == "add") {
                    rows[0].row[opt.keyId] = res.rows[0][opt.keyId];
                    addNode_data($object, rows[0].row);

                    if (opt.editLoadData) {
                        editLoadData($object, rows[0].row[opt.keyId]);
                    }
                }
                else if (res.rows[0].action == "del") {
                    delNode_data($object, rows[0].row);
                }
                else if (res.rows[0].action == "paste") {
                    pasteNode_data($object, rows[0].row);
                }
                else if (res.rows[0].action == "move") {
                    moveNode_data($object, rows[0].row);
                }
                else {
                    var row = rows[0].row;
                    var node = $object.tree("getSelected");
                    row = $.extend(node.attributes, row);

                    uppNode_data($object, row);

                    if (opt.editLoadData) {
                        editLoadData($object, rows[0].row[opt.keyId]);
                    }
                }
            } else {
                error += res.rows[0].info + "[" + res.rows[0].error + "]";
            }

            if (error != "") {
                $.yqMessager("error", error);
                if (rows[0].action == "add" ||
                    rows[0].action == "upp") {
                    showEdit($object, rows[0].action, rows[0].row);
                }
            } else {
                $.yqMessager("success", "执行成功。");
                uppActionState($object);
            }
        }
        else {
            $.yqMessager("error", res.info + "[" + res.error + "]");
        }

        opt.afterDataAction.call($object, rows, res);
    }

    function editLoadData($object, sid) {
        var opt = options($object);
        var opt_row = {
            ajaxUrl: opt.ajaxUrl,
            dbname: opt.dbname,                //数据库
            tbname: opt.tbname,                       //表
            keyid: opt.keyId,
            keyval: sid
        };
        if (typeof opt._appno != undefined) {
            opt_row.ctrlid = opt._ctrlid;
            opt_row.appno = opt._appno;
            opt_row.menuno = opt._menuno;
        }

        $.yqDbTbRow(opt_row, function (res) {
            if (res.error == 0) {
                uppNode_data($object, res.row);
            } else {
                console.log(res);
            }
        })
    }

    function addNode_data($object, row) {
        var opt = options($object);

        var row = $.yqFmToView(row, opt.titles);
        var node = {
            "id": row[opt.keyId],
            "text": $.getDisplayValue(row, opt.displayMember),
            "attributes": row,
            "state": "open"
        };

        node = opt.beforeEditNodeToUI.call($object, node);

        if (opt.loadDataType == 2) {
            node["-1"] = true;
        }

        if (row[opt.pKeyId] == opt.pKeyValue) {
            $object.tree('append', {
                data: [node]
            });
        }
        else {
            var p_node = $object.tree('find', row[opt.pKeyId]);
            if (!(p_node === null)) {
                $object.tree('append', {
                    parent: p_node.target,
                    data: [node]
                });

                $object.tree("expand", p_node.target);
            }
            else {
                alert("error");
            }
        }
        var s_node = $object.tree('find', row[opt.keyId]);
        if (!(s_node === null)) {
            $object.tree("select", s_node.target);
        }
    }

    function uppNode_data($object, row) {
        var opt = options($object);

        var node = $object.tree('find', row[opt.keyId]);
        if (!(node === null)) {
            var row = $.yqFmToView(row, opt.titles);
            node.attributes = row;
            node = opt.beforeEditNodeToUI.call($object, node);

            $object.tree('update', {
                "target": node.target,
                "text": $.getDisplayValue(row, opt.displayMember)
            });

            $object.tree('update', {
                "target": node.target,
                "attributes": row
            });

            if (!(node.iconCls === undefined ||
                node.iconCls === null ||
                node.iconCls == "")) {
                $object.tree('update', {
                    "target": node.target,
                    "iconCls": node.iconCls
                });
            } else {
                $object.tree('update', {
                    "target": node.target,
                    "iconCls": node.children === undefined ? "tree-lef" : "tree-folder"
                });
            }

            $object.tree("select", node.target);

            //剪切情况处理
            if (!(opt._cut_node === undefined)) {
                if (opt._cut_node.id == node.id) {
                    delete opt._cut_node;
                }
            }
        }
        else {
            alert("error");
        }
    }

    function delNode_data($object, row) {
        var opt = options($object);

        var node = $object.tree('find', row[opt.keyId]);
        if (!(node === null)) {
            //剪切情况处理
            if (!(opt._cut_node === undefined)) {
                if (opt._cut_node.id == node.id) {
                    delete opt._cut_node;
                }
            }

            $object.tree('remove', node.target);
        }
        else {
            alert("error");
        }
    }

    /* 
    "row": {
                "pid_field": "pid",
                "sid": "sid-6",
                "pid": "sid-7-1",
                "pid_old": "sid-7"
            }
    */
    function pasteNode_data($object, row) {
        var opt = options($object);
        var node = $object.tree('find', row[opt.keyId]);

        delete opt._cut_node;
        if (!(node === null)) {
            var data = $object.tree('pop', node.target);
            data.text = $.getDisplayValue(data.attributes, opt.displayMember);
            data.attributes[opt.pKeyId] = row[opt.pKeyId];

            if (row[opt.pKeyId] == opt.pKeyValue) {
                $object.tree("append", {
                    "data": data
                });
            }
            else {
                var p_node = $object.tree('find', row[opt.pKeyId]);
                if (!(p_node === null)) {
                    $object.tree("append", {
                        "parent": p_node.target,
                        "data": data
                    });

                    $object.tree("expand", p_node.target);
                }
                else {
                    alert("error")
                }
            }

            var n_node = $object.tree('find', row[opt.keyId]);
            $object.tree('select', n_node.target);
        }
        else {
            alert("error");
        }
    }

    /*
    {
        "pid_field": "pid",
        "pid": "sid-5",
        "ids": ["sid-5-1", "sid-5-5", "sid-5-2", "sid-5-3", "sid-5-4"],
    
    }
    */
    function moveNode_data($object, row) {
        var opt = options($object);

        s_id = null;
        var node = $object.tree("getSelected");
        if (!(node === null)) {
            s_id = node.id;
        }

        var parent = null;
        var nodes;
        if (row.pid == opt.pKeyValue) {  //根
            nodes = $object.tree("getRoots");
        }
        else {    //
            parent = $object.tree("find", row.pid);
            nodes = parent.children;
        }

        var _nodes = [];
        for (var i = (nodes.length - 1); i >= 0; i--) {
            _nodes.push($.extend({}, nodes[i]));
            var node = $object.tree("find", nodes[i].id);
            $object.tree('remove', node.target);
        }

        for (var j = 0; j < row.ids.length; j++) {
            for (var i = 0; i < _nodes.length; i++) {
                if (row.ids[j] == _nodes[i].id) {
                    if (parent === null) {  //根
                        $object.tree("append", {
                            "data": _nodes[i]
                        });
                    }
                    else {    //
                        $object.tree("append", {
                            "parent": parent.target,
                            "data": _nodes[i]
                        });
                    }

                    break;
                }
            }
        }

        if (!(s_id === null)) {
            var n_node = $object.tree('find', s_id);
            $object.tree('select', n_node.target);
        }
    }

})(jQuery);
